package com.gzk.oeno.tech.ui.sliders;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.gzk.utils.ihm.UIUtils;

public abstract class CustomizableNullableSlider extends JSlider implements ChangeListener {

	public static final String NULLVALUE_PROP = "nullableValue";
	private static final Icon EMPTY_ICON = UIUtils.loadSilentIcon("icons/forbidden_16.png");
	
	private final int nullIdx;
	private final int min;
	private final int max;
	
	private final List<JComponent> components = new ArrayList<>();
	
	public CustomizableNullableSlider(int min, int max){
		super(min - 1, max, min - 1);
		this.nullIdx = min - 1;
		this.min = min;
		this.max = max;
		
		setMajorTickSpacing(1);
		setPaintTicks(true);
		setPaintLabels(true);
		setupLabels();
		
		addChangeListener(this);
	}
	
	protected void setupLabels(){
		components.clear();
		Hashtable<Integer, JComponent> labels = new Hashtable<>();
		for (int i = min; i <= max; i++){
			JComponent comp = createLabelForIndex(Integer.valueOf(i));
			if (comp != null){
				labels.put(Integer.valueOf(i), comp);
				updateComponentUIWhenEnabled(comp, false);
				components.add(comp);
			}
		}
		
		JLabel emptyLabel = new JLabel(EMPTY_ICON);
		emptyLabel.setToolTipText("N/A");
		labels.put(Integer.valueOf(nullIdx), emptyLabel);
		
		setLabelTable(labels);
	}
	
	
	public Integer getNullableValue(){
		int index = getValue();
		return index == nullIdx ? null : Integer.valueOf(index);
	}
	
	public void setNullableValue(Integer value){
		if (value == null)
			setValue(nullIdx);
		else
			setValue(value.intValue());
	}
	
	public void stateChanged(ChangeEvent e) {
	    JSlider source = (JSlider)e.getSource();
	    if (!source.getValueIsAdjusting()) {
	    	Integer value = getNullableValue();
	    	enableCustomLabels(value != null);
	    	
	    	firePropertyChange(NULLVALUE_PROP, null, value);
	    }
	}

	protected void enableCustomLabels(boolean enable){
		for (JComponent comp : components){
			updateComponentUIWhenEnabled(comp, enable);
		}
		updateLabelUIs();
	}
	
	
	protected abstract JComponent createLabelForIndex(Integer index);
	
	protected abstract void updateComponentUIWhenEnabled(JComponent comp, boolean enabled);
}
